package com.itheima.tanhua.server.controller;

import cn.hutool.core.util.ArrayUtil;
import com.itheima.commons.constant.RedisConstant;
import com.itheima.commons.holder.TokenHolder;
import com.itheima.tanhua.autoconfig.template.OssTemplate;
import com.itheima.tanhua.dubbo.api.MovementService;
import com.itheima.tanhua.model.domain.Movement;
import com.itheima.tanhua.model.dto.RabbitMovementDto;
import com.itheima.tanhua.model.dto.RabbitMovementMediaDto;
import com.itheima.tanhua.model.vo.MovementVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.omg.CORBA.Object;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/movements")
public class MovementController {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @DubboReference
    private MovementService movementService;

    @GetMapping("/movements/recommend")
    public ResponseEntity getRecommendMovementList(@RequestParam Integer page, @RequestParam Integer pagesize) {


        return ResponseEntity.ok(null);
    }

    /**
     * 发布动态
     */
    @PostMapping
    public ResponseEntity sendMovementByMq(Movement movement,
                                           MultipartFile[] imageContent) throws IOException {
        // 一个新的结构，将前端传过来的movement数据 + 前端传过来的图片数组
        // 组装到一个结构里面
        RabbitMovementDto dto = new RabbitMovementDto();

        // 拷贝movement数据
        BeanUtils.copyProperties(movement, dto);

        // 组装图片数据
        List<RabbitMovementMediaDto> picList = new ArrayList<>();

        // 因为：MultipartFile这个类型 不能用消息队列来发送
        // 索引：我想要把MultipartFile这个类型，全部转为byte[]的形式，然后再发送给MQ
        if (ArrayUtil.isNotEmpty(imageContent)) {
            for (MultipartFile file : imageContent) {
                if (Objects.isNull(file)) {
                    continue;
                }

                // 1. 通过MultipartFile获取到他的图片数据（inputStream）
                InputStream inputStream = file.getInputStream();

                // 2. 声明一个byte数组，作为容器，承载inputStream内的内容
                byte[] bytes = new byte[inputStream.available()];

                // 3. 使用read方法，将inputStream内的内容，读取出来，写入到前面声明的byte数组容器
                inputStream.read(bytes);

                RabbitMovementMediaDto rabbitMovementMediaDto = new RabbitMovementMediaDto();
                // 获取后缀名
                rabbitMovementMediaDto.setContentType(file.getContentType());

                // 获取图片数据
                rabbitMovementMediaDto.setIs(bytes);

                // 获取图片大小
                rabbitMovementMediaDto.setSize(file.getSize());

                picList.add(rabbitMovementMediaDto);
            }
        }

        dto.setImageContent(picList);

        // 参数一：交换器名称
        String exchangeName = "tanhua.movement";

        // 参数二：routingKey:决定了我这条消息 最终要发送给哪个队列
        String key = "sendMovement";

        // 参数三：我要发送的消息内容
        rabbitTemplate.convertAndSend(exchangeName, key, dto);

        return ResponseEntity.ok("");
    }

    /**
     * 查询我的动态
     */
    @GetMapping("/all")
    public ResponseEntity findByUserId(Long userId,
                                       @RequestParam(defaultValue = "1") Integer page,
                                       @RequestParam(defaultValue = "10") Integer pagesize) {
        return ResponseEntity.ok("");
    }

    /**
     * 查询好友动态
     */
    @GetMapping
    public ResponseEntity movements(@RequestParam(defaultValue = "1") Integer page,
                                    @RequestParam(defaultValue = "10") Integer pagesize) {
        return ResponseEntity.ok(null);
    }

    /**
     * 查询推荐动态
     */
    @GetMapping("/recommend")
    public ResponseEntity recommend(@RequestParam(defaultValue = "1") Integer page,
                                    @RequestParam(defaultValue = "10") Integer pageSize) {


        List<MovementVo> recommendList = movementService.getRecommendList(page, pageSize);

        return ResponseEntity.ok("");
    }

    /**
     * 查询单条动态
     */
    @GetMapping("/{id}")
    public ResponseEntity findById(@PathVariable("id") String movementId) {
        return ResponseEntity.ok(null);
    }

    public ResponseEntity like2(@PathVariable("id") String movementId) {
        String userId = TokenHolder.getUserId();

        // 如果没有记录状态，那如何判断是否已点赞，如果不判断，可能会出现被刷的情况

        Map<String, String> message = new HashMap<>(3);
        message.put("movementId", movementId);
        message.put("userId", userId);
        message.put("createTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        // +1 操作
        Double score = redisTemplate.boundZSetOps(RedisConstant.RECOMMENT_MOVEMENT_KEY).incrementScore(movementId, 1);

        rabbitTemplate.convertAndSend("tanhua.exchange", "movementLike", message);

        return null;
    }

    /**
     * 点赞
     */
    @GetMapping("/{id}/like")
    public ResponseEntity likeByRedis(@PathVariable("id") String movementId) {

        // 步骤一：获取当前用户id
        String userId = TokenHolder.getUserId();

        // 步骤二：组装哈希结构的key
        String hashKey = RedisConstant.MOVEMENT_LIKE_HASH_KEY + userId;

        // 检测当前用户是否给movementId点过赞
        Boolean hasKey = redisTemplate.boundHashOps(hashKey).hasKey(movementId);
        if (hasKey) {
            return ResponseEntity.ok("");
        }

        // 写入有序集合（汇总）
        // 给 movementId 这条动态，执行+1操作
        Double score = redisTemplate.boundZSetOps(RedisConstant.RECOMMENT_MOVEMENT_KEY).incrementScore(movementId, 1);

        // 写入队列（明细）
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        redisTemplate.boundHashOps(hashKey).put(movementId, now);

        // 待更新记录
        redisTemplate.boundListOps("movement").leftPush(movementId + "_" + userId + "_add");


        return ResponseEntity.ok(score);
    }

    /**
     * 取消点赞
     */
    @GetMapping("/{id}/dislike")
    public ResponseEntity dislikeByRedis(@PathVariable("id") String movementId) {
        String userId = TokenHolder.getUserId();
        String hashKey = "movement:" + movementId;

        // 检测是否已存在
        Boolean hasKey = redisTemplate.boundHashOps(hashKey).hasKey(userId);
        if (!hasKey) {
            return ResponseEntity.ok("");
        }

        // 写入有序集合（汇总）
        redisTemplate.boundZSetOps("recommendMovement").incrementScore(movementId, -1);

        // 写入队列（明细）
        redisTemplate.boundHashOps(hashKey).delete(movementId);

        // 待更新记录
        redisTemplate.boundListOps("movement").leftPush(movementId + "_" + userId + "_reduce");

        return ResponseEntity.ok("");
    }

    /**
     * 喜欢
     */
    @GetMapping("/{id}/love")
    public ResponseEntity love(@PathVariable("id") String movementId) {
        return ResponseEntity.ok(null);
    }

    /**
     * 取消喜欢
     */
    @GetMapping("/{id}/unlove")
    public ResponseEntity unlove(@PathVariable("id") String movementId) {
        return ResponseEntity.ok(null);
    }

    /**
     * 谁看过我
     */
    @GetMapping("visitors")
    public ResponseEntity queryVisitorsList() {
        return ResponseEntity.ok(null);
    }
}